package com.example.demo.com.java8.lambda;

import org.junit.Test;

import java.io.PrintStream;
import java.util.*;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

/**
 * 方法引用：若lambda体中的内容有方法已经实现了，可以使用"方法引用"
 *   可以理解为是lambda表达式的另一种表示方式
 *
 *
 *   注意：lambda 体中调用方法的参数和返回值类型要和函数式接口中的抽象方法返回值类型要保持一致
 * 一、主要有三种语法格式
 * 对象::实例方法名
 * 类::静态方法名
 * 类::实例方法名
 *
 * 二、构造器引用：
 * className::new
 *
 *
 *
 * 构造器引用要与函数式接口的抽象方法的参数列表保持一致
 * @author chengfei5
 * @date 2018/8/20
 */
public class TestMethodRef {
    @Test
    public void test1(){
        //实例方法
        Consumer<String> consumer = x -> System.out.println(x);
        //对象::方法名
        PrintStream ps = System.out;
        Consumer<String> consumer1 = ps::println;

        Consumer<String> consumer2 = System.out::println;
        consumer2.accept("hello world");
    }

    @Test
    public void test2(){
        Apple apple = new Apple(100,"green");
        Supplier<String> supplier = ()->apple.getColor();
        System.out.println(supplier.get());
        //对象::方法名
        Supplier<String> supplier1 = apple::getColor;
        System.out.println(supplier1.get());
    }

    /**
     * 类::静态方法
     */
    @Test
    public void test3(){
        Comparator<Integer> comparator = (x,y)-> Integer.compare(x,y);
        //静态方法
        Comparator<Integer> comparator1 = Integer::compare;

        System.out.println(comparator1.compare(5,5));
    }

    /**
     * 类::实例方法名
     * 只有当第一个参数是实例方法的调用者，第二个参数是实例方法的参数时才可这么写
     */
    @Test
    public void test4(){
        BiPredicate<String,String> biPredicate = (x,y)->x.equals(y);
        BiPredicate<String,String> biPredicate1 = String::equals;
        biPredicate.test("test","test");
    }

    /**
     * 构造器引用
     */
    @Test
    public void test5(){
        Supplier<Apple> supplier = ()->new Apple(120,"red");

        Supplier<Apple> supplier1 = Apple::new;
        System.out.println(supplier1.get());



    }

    @Test
    public void test6(){
        Function<Integer,Apple> function = x->new Apple(130);
        Function<Integer,Apple> function1 = Apple::new;
        System.out.println(function1.apply(130));
    }

    /**
     * 数组引用，集合引用，map引用
     */
    @Test
    public void test7(){
        Function<Integer,String[]> function = x->new String[x];
        String[] strs = function.apply(10);
        System.out.println(strs.length);
        Function<Integer,String[]> function1 = String[]::new;
        String[] str2 = function.apply(20);
        System.out.println(str2.length);

        Supplier<List<String>> supplier2 = ArrayList::new;
        System.out.println(supplier2.get());
        Supplier<Map<Integer,String>> supplier3 = HashMap::new;
        System.out.println(supplier3.get());
    }
}
